package main

import "fmt"

// 有时候我们需要在一个类的基础上扩展另一个类，例如，一个披萨类，
// 你可以在披萨类的基础上增加番茄披萨类和芝士披萨类。
// 此时就可以使用装饰模式，简单来说，装饰模式就是将对象封装到另一个对象中，用以为原对象绑定新的行为

type pizza interface {
	getPrice() int
}
type base struct{}

func (p *base) getPrice() int {
	return 15
}

type tomatoTopping struct {
	pizza pizza
}

func (c *tomatoTopping) getPrice() int {
	pizzaPrice := c.pizza.getPrice()
	return pizzaPrice + 10
}

type cheeseTopping struct {
	pizza pizza
}

func (c *cheeseTopping) getPrice() int {
	pizzaPrice := c.pizza.getPrice()
	return pizzaPrice + 20
}

func ExampleDecorator() {
	pizza := &base{}

	pizzaWithCheese := &cheeseTopping{pizza: pizza}

	pizzaWithCheeseAndTomato := &tomatoTopping{pizza: pizzaWithCheese}

	fmt.Printf("price is %d\n", pizzaWithCheeseAndTomato.getPrice())
}
